package com.platform.common.utils;


import org.springframework.beans.BeanUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class ObjectContrast {

    public static StringBuffer createUpdateLogContent(Object dbData, Object pageData) {
        try {
            StringBuffer buffer = new StringBuffer();
            // 将对象赋值到新的实体中，减少字段的使用
            Object dbE = new Object();
            BeanUtils.copyProperties(dbData, dbE);
            Object pageE = new Object();
            //拷贝对象
            BeanUtils.copyProperties(pageData, pageE);
            // 获取所有数据库属性
            Field[] dbFields = dbE.getClass().getDeclaredFields();
            //存储key:属性名，value:属性值
            Map<String, String> dbNameAndValueMap = new LinkedHashMap<String, String>();
            //遍历所有属性，生成Map
            for (Field field : dbFields) {
                // 解除私有限定
                field.setAccessible(true);
                dbNameAndValueMap.put(field.getName(), field.get(dbE).toString());
            }
            // 遍历页面新的属性值
            Field[] pageFields = pageE.getClass().getDeclaredFields();
            for (Field field : pageFields) {
                // 解除私有限定
                field.setAccessible(true);
                if (dbNameAndValueMap.containsKey(field.getName())) {
                    // 判断值是否修改
                    if (!dbNameAndValueMap.get(field.getName()).equals(field.get(pageE).toString())) {
                        buffer.append("属性【" + field.getName() + "】由【" + dbNameAndValueMap.get(field.getName()) + "】修改为【" + field.get(pageE).toString() + "】");
                    }
                }
            }
            return buffer;
        } catch (Exception e) {
            return new StringBuffer();
        }
    }

    /**
     * @param beginModel 旧数据model
     * @param afterModel 新数据model
     * @return 返回新数据和旧数据的map集合
     */
    public static Map<String, Map<String, Object>> judgeAttributesIsEqual(Object beginModel, Object afterModel) {
        /**
         *  创建两个个Map<String,Object>
         *  分别存储改动前 改动后的数据
         */
        Map<String, Object> beginMap = new HashMap<>(16);
        Map<String, Object> afterMap = new HashMap<>(16);
        Map<String, Map<String, Object>> list = new HashMap<>(16);
        /**
         *  model换成需要遍历的实体
         *  获取实体类的所有属性，返回Field数组
         */
        Field[] field = beginModel.getClass().getDeclaredFields();
        Field[] field2 = afterModel.getClass().getDeclaredFields();
        try {
            // 遍历所有属性
            for (int i = 0; i < field.length; i++) {
                // 获取属性的名字
                String name = field[i].getName();
                // 将属性的首字符大写，方便构造get，set方法
                name = name.substring(0, 1).toUpperCase() + name.substring(1);
                for (int j = 0; j < field2.length; j++) {
                    // 获取属性的名字
                    String name2 = field2[j].getName();
                    // 将属性的首字符大写，方便构造get，set方法
                    name2 = name2.substring(0, 1).toUpperCase() + name2.substring(1);
                    if ("Id".equals(name)) {
                        break;
                    }
                    //判断属性名是否相同
                    if (name.equals(name2) && !"serialversionuid".equals(name.toLowerCase())) {
                        Method m = beginModel.getClass().getMethod("get" + name);
                        Method m1 = afterModel.getClass().getMethod("get" + name2);
                        // 调用getter方法获取属性值
                        Object value = m.invoke(beginModel);
                        Object value2 = m1.invoke(afterModel);
                        /**
                         *  判断属性值是否相等 相等则跳出当前循环执行下一个属性对比
                         *  不想等存储相关数据同时进行下一个属性比较
                         */
                        if (value == null || value2 == null) {
                            break;
                        }
                        if (value.toString().equals(value2.toString())) {
                            break;
                        } else {
                            beginMap.put(name, value + "=>" + value2);
                            afterMap.put(name, value2);
                            break;
                        }

                    }
                }
            }
            list.put("old", beginMap);
            list.put("new", afterMap);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return list;
    }
}
